﻿#region 头注释
/******************************************************************************
文件名称    :   Patient.cs
创建日期    :   2011/5/11 22:04:21
功能描述    :   病人信息实体类
修改日志    :   
    2011-05-11 22:04  马利
*******************************************************************************/
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Newtonsoft.Json;
using Dare.Utilities.Data;
using Dare.Utilities;

namespace Stone.Components.Entities
{
    /// <summary>
    /// 病人信息实体类
    /// </summary>
    public class Patient : EntityBase<Patient, long>
    {
        #region 构造函数

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public Patient()
            : base()
        {
            base.xmlSerializer = new DefaultXmlSerializer(this);
            base.jsonSerializer = new DefaultJsonSerializer(this);
        }

        public override void Reset()
        {
            name = String.Empty;
            nameAbbr = null;
            sex = (SexEnum)0;
            birthday = null;
            age = null;
            height = null;
            weight = null;
            number = null;
            bmi = null;
            address = null;
            telephone = null;
            cellphone = null;
            postcode = null;
            history = null;
            historyId = null;
            hasMenses = null;
            mensesCycle = null;
            amenorrheaTime = null;
            comment = null;
            timeStamp = DateTime.MinValue;
        }

        public override Patient CreateNew()
        {
            return new Patient();
        }

        #endregion

        #region 属性

        /// <summary>
        /// 获取实体类型
        /// </summary>
        public override EntityType EntityType
        {
            get { return EntityType.Patient; }
        }

        /// <summary>
        /// 获取或设置姓名
        /// </summary>
        public string Name
        {
            get { return name; }
            set
            {
                if (entityState == EntityState.Saved && name != value) entityState = EntityState.Changed;
                name = value;
            }
        }
        protected string name;

        /// <summary>
        /// 获取或设置姓名拼音缩写
        /// </summary>
        public string NameAbbr
        {
            get { return nameAbbr; }
            set
            {
                if (entityState == EntityState.Saved && nameAbbr != value) entityState = EntityState.Changed;
                nameAbbr = value;
            }
        }
        protected string nameAbbr;

        /// <summary>
        /// 获取或设置性别
        /// </summary>
        public SexEnum Sex
        {
            get { return sex; }
            set
            {
                if (entityState == EntityState.Saved && sex != value) entityState = EntityState.Changed;
                sex = value;
            }
        }
        protected SexEnum sex;

        /// <summary>
        /// 获取或设置生日
        /// </summary>
        public DateTime? Birthday
        {
            get { return birthday; }
            set
            {
                if (entityState == EntityState.Saved && birthday != value) entityState = EntityState.Changed;
                birthday = value;
            }
        }
        protected DateTime? birthday;

        /// <summary>
        /// 获取或设置年龄
        /// </summary>
        public int? Age
        {
            get { return age; }
            set
            {
                if (entityState == EntityState.Saved && age != value) entityState = EntityState.Changed;
                age = value;
            }
        }
        protected int? age;

        /// <summary>
        /// 获取或设置身高(cm)
        /// </summary>
        public decimal? Height
        {
            get { return height; }
            set
            {
                if (entityState == EntityState.Saved && height != value) entityState = EntityState.Changed;
                height = value;
            }
        }
        protected decimal? height;

        /// <summary>
        /// 获取或设置体重(斤)
        /// </summary>
        public decimal? Weight
        {
            get { return weight; }
            set
            {
                if (entityState == EntityState.Saved && weight != value) entityState = EntityState.Changed;
                weight = value;
            }
        }
        protected decimal? weight;

        /// <summary>
        /// 获取或设置住院号
        /// </summary>
        public int? Number
        {
            get { return number; }
            set
            {
                if (entityState == EntityState.Saved && number != value) entityState = EntityState.Changed;
                number = value;
            }
        }
        protected int? number;

        /// <summary>
        /// 获取或设置BMI指数(体重公斤数除以身高米数平方)
        /// </summary>
        public decimal? Bmi
        {
            get { return bmi; }
            set
            {
                if (entityState == EntityState.Saved && bmi != value) entityState = EntityState.Changed;
                bmi = value;
            }
        }
        protected decimal? bmi;

        /// <summary>
        /// 获取或设置家庭地址
        /// </summary>
        public string Address
        {
            get { return address; }
            set
            {
                if (entityState == EntityState.Saved && address != value) entityState = EntityState.Changed;
                address = value;
            }
        }
        protected string address;

        /// <summary>
        /// 获取或设置电话
        /// </summary>
        public string Telephone
        {
            get { return telephone; }
            set
            {
                if (entityState == EntityState.Saved && telephone != value) entityState = EntityState.Changed;
                telephone = value;
            }
        }
        protected string telephone;

        /// <summary>
        /// 获取或设置手机
        /// </summary>
        public string Cellphone
        {
            get { return cellphone; }
            set
            {
                if (entityState == EntityState.Saved && cellphone != value) entityState = EntityState.Changed;
                cellphone = value;
            }
        }
        protected string cellphone;

        /// <summary>
        /// 获取或设置邮政编码
        /// </summary>
        public string Postcode
        {
            get { return postcode; }
            set
            {
                if (entityState == EntityState.Saved && postcode != value) entityState = EntityState.Changed;
                postcode = value;
            }
        }
        protected string postcode;

        /// <summary>
        /// 获取或设置既往史
        /// </summary>
        public History History
        {
            get { return history; }
            set
            {
                if (entityState == EntityState.Saved && value != null && value.Id != historyId) entityState = EntityState.Changed;
                history = value;
            }
        }
        protected History history;

        /// <summary>
        /// 获取或设置既往史ID
        /// </summary>
        public long? HistoryId
        {
            get { return history == null ? historyId : history.Id; }
            set { historyId = value; }
        }
        protected long? historyId;

        /// <summary>
        /// 获取或设置月经有无
        /// </summary>
        public bool? HasMenses
        {
            get { return hasMenses; }
            set
            {
                if (entityState == EntityState.Saved && hasMenses != value) entityState = EntityState.Changed;
                hasMenses = value;
            }
        }
        protected bool? hasMenses;

        /// <summary>
        /// 获取或设置月经周期(天)
        /// </summary>
        public int? MensesCycle
        {
            get { return mensesCycle; }
            set
            {
                if (entityState == EntityState.Saved && mensesCycle != value) entityState = EntityState.Changed;
                mensesCycle = value;
            }
        }
        protected int? mensesCycle;

        /// <summary>
        /// 获取或设置闭经时间
        /// </summary>
        public int? AmenorrheaTime
        {
            get { return amenorrheaTime; }
            set
            {
                if (entityState == EntityState.Saved && amenorrheaTime != value) entityState = EntityState.Changed;
                amenorrheaTime = value;
            }
        }
        protected int? amenorrheaTime;

        /// <summary>
        /// 获取或设置备注
        /// </summary>
        public string Comment
        {
            get { return comment; }
            set
            {
                if (entityState == EntityState.Saved && comment != value) entityState = EntityState.Changed;
                comment = value;
            }
        }
        protected string comment;

        /// <summary>
        /// 获取或设置更新时间戳
        /// </summary>
        public DateTime TimeStamp
        {
            get { return timeStamp; }
            set
            {
                if (entityState == EntityState.Saved && timeStamp != value) entityState = EntityState.Changed;
                timeStamp = value;
            }
        }
        protected DateTime timeStamp;

        /// <summary>
        /// 就医信息设置
        /// </summary>
        public List<Hospitalization> Hospitalization { set; get; }


        #endregion

        #region 方法

        #endregion

        #region 实体复制相关方法

        /// <summary>
        /// 复制当前实体属性到指定实体上
        /// </summary>
        /// <param name="entity">要把属性复制到的实体</param>
        /// <returns>返回传入的实体</returns>
        public override Patient CopyTo(Patient entity)
        {
            if (base.CopyTo(entity) == null) return null;

            entity.name = this.name;
            entity.nameAbbr = this.nameAbbr;
            entity.sex = this.sex;
            entity.birthday = this.birthday;
            entity.age = this.age;
            entity.height = this.height;
            entity.weight = this.weight;
            entity.number = this.number;
            entity.bmi = this.bmi;
            entity.address = this.address;
            entity.telephone = this.telephone;
            entity.cellphone = this.cellphone;
            entity.postcode = this.postcode;
            entity.history = this.history;
            entity.historyId = this.historyId;
            entity.hasMenses = this.hasMenses;
            entity.mensesCycle = this.mensesCycle;
            entity.amenorrheaTime = this.amenorrheaTime;
            entity.comment = this.comment;
            entity.timeStamp = this.timeStamp;

            return entity;
        }

        #endregion

        #region 默认XML序列器类

        public class DefaultXmlSerializer : XmlSerializerBase, IEntityXmlSerializer<Patient>
        {
            Patient entity;
            public DefaultXmlSerializer(Patient entity)
                : base(entity.GetType().Name)
            {
                this.entity = entity;
            }

            public Patient Entity
            {
                get { return entity; }
                set { entity = value; }
            }

            protected override void BeforeReadXml()
            {
                entity.Reset();
            }

            /// <summary>
            /// 读取XML属性
            /// </summary>
            /// <param name="name">属性名</param>
            /// <param name="value">属性值</param>
            /// <param name="reader">XML读取器</param>
            internal override void ReadXmlAttribute(string name, string value, XmlReader reader)
            {
                switch (name)
                {
                    case "id":
                        entity.id = XmlConvert.ToInt64(value);
                        break;
                    case "timeStamp":
                        entity.timeStamp = new DateTime(long.Parse(value));
                        break;
                    case "entityState":
                        entity.entityState = (EntityState)Enum.Parse(typeof(EntityState), value, true);
                        break;
                }
            }

            /// <summary>
            /// 读取XML子节点
            /// </summary>
            /// <param name="name">节点名</param>
            /// <param name="reader">XML读取器</param>
            internal override void ReadXmlChildElement(string name, XmlReader reader)
            {
                switch (name)
                {
                    case "Name":
                        entity.name = reader.ReadElementString();
                        break;
                    case "NameAbbr":
                        entity.nameAbbr = reader.ReadElementString();
                        break;
                    case "Sex":
                        entity.sex = (SexEnum)Enum.Parse(typeof(SexEnum), reader.ReadElementString(), true);//XmlConvert.ToBoolean(reader.ReadElementString());
                        break;
                    case "Birthday":
                        entity.birthday = XmlConvert.ToDateTime(reader.ReadElementString(), XmlDateTimeSerializationMode.Utc);
                        break;
                    case "Age":
                        entity.age = XmlConvert.ToInt32(reader.ReadElementString());
                        break;
                    case "Height":
                        entity.height = XmlConvert.ToDecimal(reader.ReadElementString());
                        break;
                    case "Weight":
                        entity.weight = XmlConvert.ToDecimal(reader.ReadElementString());
                        break;
                    case "Number":
                        entity.number = XmlConvert.ToInt32(reader.ReadElementString());
                        break;
                    case "Bmi":
                        entity.bmi = XmlConvert.ToDecimal(reader.ReadElementString());
                        break;
                    case "Address":
                        entity.address = reader.ReadElementString();
                        break;
                    case "Telephone":
                        entity.telephone = reader.ReadElementString();
                        break;
                    case "Cellphone":
                        entity.cellphone = reader.ReadElementString();
                        break;
                    case "Postcode":
                        entity.postcode = reader.ReadElementString();
                        break;
                    case "HistoryId":
                        entity.historyId = XmlConvert.ToInt64(reader.ReadElementString());
                        break;
                    case "HasMenses":
                        entity.hasMenses = XmlConvert.ToBoolean(reader.ReadElementString());
                        break;
                    case "MensesCycle":
                        entity.mensesCycle = XmlConvert.ToInt32(reader.ReadElementString());
                        break;
                    case "AmenorrheaTime":
                        entity.amenorrheaTime = XmlConvert.ToInt32(reader.ReadElementString());
                        break;
                    case "Comment":
                        entity.comment = reader.ReadElementString();
                        break;
                }
            }

            /// <summary>
            /// 写入XML属性
            /// </summary>
            /// <param name="writer">XML编写器</param>
            internal override void WriteXmlAttributes(XmlWriter writer)
            {
                writer.WriteAttributeString("id", XmlConvert.ToString(entity.Id));
                writer.WriteAttributeString("timeStamp", entity.TimeStamp.Ticks.ToString());
                writer.WriteAttributeString("entityState", entity.EntityState.ToString());
            }

            /// <summary>
            /// 写入XML子节点
            /// </summary>
            /// <param name="writer">XML编写器</param>
            internal override void WriteXmlChildElements(XmlWriter writer)
            {
                writer.WriteElementString("Name", entity.Name);
                if (entity.NameAbbr != null) writer.WriteElementString("NameAbbr", entity.NameAbbr);
                writer.WriteElementString("Sex", entity.sex.ToString());
                if (entity.Birthday != null) writer.WriteElementString("Birthday", XmlConvert.ToString(entity.Birthday.Value, XmlDateTimeSerializationMode.Utc));
                if (entity.Age != null) writer.WriteElementString("Age", XmlConvert.ToString(entity.Age.Value));
                if (entity.Height != null) writer.WriteElementString("Height", XmlConvert.ToString(entity.Height.Value));
                if (entity.Weight != null) writer.WriteElementString("Weight", XmlConvert.ToString(entity.Weight.Value));
                if (entity.Number != null) writer.WriteElementString("Number", XmlConvert.ToString(entity.Number.Value));
                if (entity.Bmi != null) writer.WriteElementString("Bmi", XmlConvert.ToString(entity.Bmi.Value));
                if (entity.Address != null) writer.WriteElementString("Address", entity.Address);
                if (entity.Telephone != null) writer.WriteElementString("Telephone", entity.Telephone);
                if (entity.Cellphone != null) writer.WriteElementString("Cellphone", entity.Cellphone);
                if (entity.Postcode != null) writer.WriteElementString("Postcode", entity.Postcode);
                if (entity.HistoryId != null) writer.WriteElementString("HistoryId", XmlConvert.ToString(entity.HistoryId.Value));
                if (entity.HasMenses != null) writer.WriteElementString("HasMenses", XmlConvert.ToString(entity.HasMenses.Value));
                if (entity.MensesCycle != null) writer.WriteElementString("MensesCycle", XmlConvert.ToString(entity.MensesCycle.Value));
                if (entity.AmenorrheaTime != null) writer.WriteElementString("AmenorrheaTime", XmlConvert.ToString(entity.AmenorrheaTime.Value));
                if (entity.Comment != null) writer.WriteElementString("Comment", entity.Comment);
            }
        }

        #endregion

        #region 默认Json序列化器类

        public class DefaultJsonSerializer : JsonSerializerBase, IEntityJsonSerializer<Patient>
        {
            Patient entity;
            public DefaultJsonSerializer(Patient entity)
                : base()
            {
                this.entity = entity;
            }

            public Patient Entity
            {
                get { return entity; }
                set { entity = value; }
            }

            /// <summary>
            /// 读取JSON属性
            /// </summary>
            /// <param name="propName">属性名称</param>
            /// <param name="propValue">属性值</param>
            /// <param name="reader">JSON读取器</param>
            protected override void ReadJsonProperty(string propName, object propValue, JsonReader reader)
            {
                switch (propName)
                {
                    case "id":
                        entity.id = DbConvert.ToNullableInt64(propValue) ?? entity.id;
                        break;
                    case "name":
                        entity.name = Convert.ToString(propValue) ?? entity.name;
                        break;
                    case "nameAbbr":
                        entity.nameAbbr = Convert.ToString(propValue) ?? entity.nameAbbr;
                        break;
                    case "sex":
                        entity.sex = (SexEnum)(DbConvert.ToNullableInt32(propValue) ?? (int)entity.sex);//DbConvert.ToNullableBoolean(propValue) ?? entity.sex;
                        break;
                    case "birthday":
                        entity.birthday = DbConvert.ToNullableDateTime(propValue) ?? entity.birthday;
                        break;
                    case "age":
                        entity.age = DbConvert.ToNullableInt32(propValue) ?? entity.age;
                        break;
                    case "height":
                        entity.height = DbConvert.ToNullableDecimal(propValue) ?? entity.height;
                        break;
                    case "weight":
                        entity.weight = DbConvert.ToNullableDecimal(propValue) ?? entity.weight;
                        break;
                    case "number":
                        entity.number = DbConvert.ToNullableInt32(propValue) ?? entity.number;
                        break;
                    case "bmi":
                        entity.bmi = DbConvert.ToNullableDecimal(propValue) ?? entity.bmi;
                        break;
                    case "address":
                        entity.address = Convert.ToString(propValue) ?? entity.address;
                        break;
                    case "telephone":
                        entity.telephone = Convert.ToString(propValue) ?? entity.telephone;
                        break;
                    case "cellphone":
                        entity.cellphone = Convert.ToString(propValue) ?? entity.cellphone;
                        break;
                    case "postcode":
                        entity.postcode = Convert.ToString(propValue) ?? entity.postcode;
                        break;
                    case "historyId":
                        entity.historyId = DbConvert.ToNullableInt64(propValue) ?? entity.historyId;
                        break;
                    case "hasMenses":
                        entity.hasMenses = DbConvert.ToNullableBoolean(propValue) ?? entity.hasMenses;
                        break;
                    case "mensesCycle":
                        entity.mensesCycle = DbConvert.ToNullableInt32(propValue) ?? entity.mensesCycle;
                        break;
                    case "amenorrheaTime":
                        entity.amenorrheaTime = DbConvert.ToNullableInt32(propValue) ?? entity.amenorrheaTime;
                        break;
                    case "comment":
                        entity.comment = Convert.ToString(propValue) ?? entity.comment;
                        break;
                    case "timeStamp":
                        entity.timeStamp = new DateTime(DbConvert.ToNullableInt64(propValue) ?? 0);
                        break;
                }
            }

            /// <summary>
            /// 写入JSON属性
            /// </summary>
            /// <param name="writer">JSON编写器</param>
            protected override void WriteJsonProperties(JsonWriter writer)
            {

                //病人id
                writer.WritePropertyName("id");
                writer.WriteValue(entity.Id);

                //姓名
                writer.WritePropertyName("name");
                writer.WriteValue(entity.Name);

                //姓名拼音缩写
                writer.WritePropertyName("nameAbbr");
                if (entity.NameAbbr == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.NameAbbr);
                }

                //性别
                writer.WritePropertyName("sex");
                writer.WriteValue(entity.Sex);

                //生日
                writer.WritePropertyName("birthday");
                if (entity.Birthday == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Birthday.Value);
                }

                //年龄
                writer.WritePropertyName("age");
                if (entity.Age == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Age.Value);
                }

                //身高(cm)
                writer.WritePropertyName("height");
                if (entity.Height == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Height.Value);
                }

                //体重(斤)
                writer.WritePropertyName("weight");
                if (entity.Weight == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Weight.Value);
                }

                //住院号
                writer.WritePropertyName("number");
                if (entity.Number == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Number.Value);
                }

                //BMI指数(体重公斤数除以身高米数平方)
                writer.WritePropertyName("bmi");
                if (entity.Bmi == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Bmi.Value);
                }

                //家庭地址
                writer.WritePropertyName("address");
                if (entity.Address == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Address);
                }

                //电话
                writer.WritePropertyName("telephone");
                if (entity.Telephone == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Telephone);
                }

                //手机
                writer.WritePropertyName("cellphone");
                if (entity.Cellphone == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Cellphone);
                }

                //邮政编码
                writer.WritePropertyName("postcode");
                if (entity.Postcode == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Postcode);
                }

                //既往史ID
                writer.WritePropertyName("historyId");
                if (entity.HistoryId == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.HistoryId.Value);
                }

                //月经有无
                writer.WritePropertyName("hasMenses");
                if (entity.HasMenses == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.HasMenses.Value);
                }

                //月经周期(天)
                writer.WritePropertyName("mensesCycle");
                if (entity.MensesCycle == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.MensesCycle.Value);
                }

                //闭经时间
                writer.WritePropertyName("amenorrheaTime");
                if (entity.AmenorrheaTime == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.AmenorrheaTime.Value);
                }

                //备注
                writer.WritePropertyName("comment");
                if (entity.Comment == null)
                {
                    writer.WriteNull();
                }
                else
                {
                    writer.WriteValue(entity.Comment);
                }

                //更新时间戳
                writer.WritePropertyName("timeStamp");
                writer.WriteValue(entity.TimeStamp.Ticks);
            }
        }


        #endregion
    }

    /// <summary>
    /// 病人性别枚举
    /// </summary>
    public enum SexEnum
    {
        [EnumDisplayName("男")]
        male = 0,
        [EnumDisplayName("女")]
        female = 1,
    }
}